package team.hyznrj.studentsys.entity;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.util.StringUtils;

import com.mongodb.BasicDBObject;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@NoArgsConstructor
@ToString
public class SGQMainMessageEntity {
	/**
	 * 是否是2018年政策后的新表（学分制表格）
	 */
	private boolean isNewTable;
	/**
	 * 学年
	 */
	private String academicYear;
	/**
	 * 学期
	 */
	private Integer item;
	/**
	 * 学科数量统计
	 */
	private Map<String, Integer> subjectCount;
	/**
	 * 学科分值统计
	 */
	private Map<String, Double> subjectNum;
	/**
	 * 学科必修统计
	 */
	private Map<String, Boolean> subjectBool;
	/**
	 * 班级统计
	 */
	private List<String> clas;
	/**
	 * 学院统计
	 */
	private List<String> academy;
	/**
	 * 人数统计
	 */
	private Integer mainCount;
	/**
	 * 学号->学生所有信息的映射
	 */
	private Map<String, SGQEntity> stuMessage;
	/**
	 * 学号存储缓存
	 */
	private List<String> cacheSnoList;
	/**
	 * 班级存储缓存
	 */
	private String cacheClas;
	/**
	 * 学院存储缓存
	 */
	private String cacheAcademy;
	/**
	 * 是否显示体育课
	 */
	private Boolean showPeCache;
	/**
	 * 参数
	 */
	private ExcelStaticParam param;
	/**
	 * 创作者
	 */
	private String flag;
	/**
	 * 剩余奖学金数量
	 */
	private Map<String, Integer> rewardsNum;
	/**
	 * 贫困存储
	 */
	private Map<String, Integer> povertyMap;
	public final static String[] REWARD_NAME = { "一等奖", "二等奖", "三等奖", "余量" };

	/**
	 * 获取学生信息里的学号(按从小到大排)
	 * 
	 * @return
	 */
	public List<String> getStuSno() {
		return cacheSnoList;
	}

	public boolean showPeCol() {
		if (showPeCache == null) {
			if (stuMessage != null) {
				int count = 0;
				Set<String> keySet = stuMessage.keySet();
				for (String sno : keySet) {
					SGQEntity sgqEntity = stuMessage.get(sno);
					if (sgqEntity.getCourseEntity().getCountPE() > 0) {
						count++;
					}
				}
				double rate = (double) count / stuMessage.size();
				showPeCache = rate > param.getEXCEL_SUBJECT_SELECTIVE();
			}
		}

		return showPeCache;
	}

	/**
	 * 获取科目的总数量,出错则返回空List
	 * 
	 * @return
	 */
	public List<String> getSubjectLarge() {
		List<String> main = new ArrayList<>();
		if (subjectCount != null && !subjectCount.isEmpty()) {
			Set<String> keySet = subjectCount.keySet();
			for (String str : keySet) {
				if (subjectBool.get(str)) {
					Integer count = subjectCount.get(str);
					double per = Double.valueOf(count) / Double.valueOf(mainCount);
					if (per >= param.getEXCEL_SUBJECT_SELECTIVE()) {
						main.add(str);
					}
				}
			}
		}
		return main;
	}

	/**
	 * 获取班级的信息（按从小到大排序） 格式：XXXX、XXXX、XXXX
	 * 
	 * @return
	 */
	public String getClasValue() {
		if (StringUtils.isEmpty(cacheClas)) {
			if (clas != null && clas.size() > 0) {
				StringBuffer sbf = new StringBuffer();
				for (int i = 0; i < clas.size(); i++) {
					String x = clas.get(i);
					String tmp = x;
					int index = i;
					for (int j = i + 1; j < clas.size(); j++) {
						String y = clas.get(j);
						if (tmp.compareTo(y) > 0) {
							tmp = y;
							index = j;
						}
					}
					if (x.compareTo(tmp) > 0) {
						clas.set(i, tmp);
						clas.set(index, x);
					}
					sbf.append(clas.get(i) + "、");
				}
				if (sbf.length() > 0) {
					sbf.deleteCharAt(sbf.length() - 1);
				}
				cacheClas = sbf.toString();
			}
		}
		return cacheClas;
	}

	/**
	 * 获取学院字段 格式：XXXX、XXXX、XXXX
	 * 
	 * @return
	 */
	public String getAcademyValue() {
		StringBuffer sbf = new StringBuffer();
		if (academy != null) {
			for (int i = 0; i < academy.size(); i++) {
				sbf.append(academy.get(i));
				if (i != academy.size() - 1) {
					sbf.append("、");
				}
			}
		}
		return sbf.toString();
	}

	public void setStuMessage(Map<String, SGQEntity> stuMessage, ExcelStaticParam param,
			Map<String, Boolean> subjectBool) {
		this.param = param;
		this.stuMessage = stuMessage;
		this.subjectBool = subjectBool;
		List<SGQEntity> list = new ArrayList<>();
		for (String str : stuMessage.keySet()) {
			SGQEntity sgqEntity = stuMessage.get(str);
			sgqEntity.setParam(param);
			list.add(sgqEntity);
		}
		if (stuMessage != null) {
			/**
			 * 排序列表
			 */
			List<Double> culturalList = new ArrayList<>();
			List<Double> moralList = new ArrayList<>();
			List<Double> socalList = new ArrayList<>();
			List<Double> mainCount = new ArrayList<>();
			/**
			 * 参数初始化
			 */
			/**
			 * 一等奖、二等奖、三等奖数量 总数
			 */
			// 总学生人数
			int mainStu = stuMessage.size();
			int f1 = param.getLeastRewardNumber(1, mainStu);
			int f2 = param.getLeastRewardNumber(2, mainStu);
			int f3 = param.getLeastRewardNumber(3, mainStu);
			int mainReward = f1 + f2 + f3;
			boolean canContinue = true;
			/**
			 * 判断条件1:获奖人数不超过30%
			 */
			int size = stuMessage.size();
			if (mainReward > size * param.getREWARD_RATE_IN_CLASS_PERCENT()) {
				/**
				 * 如果是超过30%，就按30%来算
				 */
				mainReward = (int) (size * param.getREWARD_RATE_IN_CLASS_PERCENT());
			}
			/**
			 * 按学年总测来排名
			 */
			for (int i = 0; i < list.size(); i++) {
				int index = i;
				SGQEntity sgq1 = list.get(i);
				SGQEntity sgq2 = null;
				double val = sgq1.getAllMainCount();
				for (int j = i; j < list.size(); j++) {
					sgq2 = list.get(j);
					double val2 = sgq2.getAllMainCount();
					if (val < val2) {
						index = j;
						val = val2;
					}
				}
				if (index != i) {
					sgq2 = list.get(index);
					list.set(i, sgq2);
					list.set(index, sgq1);
				}
				if (cacheSnoList == null) {
					cacheSnoList = new ArrayList<>();
				}
				SGQEntity sgqEntity = list.get(i);
				List<Double> tmp1 = sgqEntity.getMorality();
				List<Double> tmp2 = sgqEntity.getSocalQuality();
				cacheSnoList.add(sgqEntity.getSno());
				culturalList.add(sgqEntity.get_AvgCultrualGrade());
				moralList.add(tmp1.get(tmp1.size() - 1));
				socalList.add(tmp2.get(tmp2.size() - 1));
				mainCount.add(sgqEntity.getAllMainCount());
			}
			/**
			 * 为 专业文化素质、思想道德素质、社会实践能力排名
			 */
			Map<Double, Integer> order1 = DoubleSort.getOrder(culturalList);
			Map<Double, Integer> order2 = DoubleSort.getOrder(moralList);
			Map<Double, Integer> order3 = DoubleSort.getOrder(socalList);
			Map<Double, Integer> order4 = DoubleSort.getOrder(mainCount);
			String[] orderName = SGQEntity.ORDER_NAME;
			for (int i = 0; i < list.size(); i++) {
				SGQEntity sgqEntity = list.get(i);
				List<Double> tmp1 = sgqEntity.getMorality();
				List<Double> tmp2 = sgqEntity.getSocalQuality();
				Integer i1 = order1.get(sgqEntity.get_AvgCultrualGrade());
				Integer i2 = order2.get(tmp1.get(tmp1.size() - 1));
				Integer i3 = order3.get(tmp2.get(tmp2.size() - 1));
				Integer i4 = order4.get(sgqEntity.getAllMainCount());
				/**
				 * "专业文化素质名次", "思想道德素质名次", "社会实践能力名次", "总评名次"
				 */
				Map<String, Integer> myOrder = new HashMap<>();
				myOrder.put(orderName[0], i1);
				myOrder.put(orderName[1], i2);
				myOrder.put(orderName[2], i3);
				myOrder.put(orderName[3], i4);
				sgqEntity.setMyOrder(myOrder);

				/**
				 * 奖学金等级设置 mainReward:总数 f1:一等奖数量 f2:二等奖数量 f3:三等奖数量
				 */
				if (canContinue && mainReward > 0) {
					if (sgqEntity.getGGNum() > 0) {
						/** 如果挂科则免谈 */
						continue;
					}
					CourseEntity courseEntity = sgqEntity.getCourseEntity();
					if (courseEntity != null) {
						double avgGrade = courseEntity.getAvgGrade();
						/**
						 * 1.奖学金必须在前PARAM%名内 2.有名额 3.成绩大于要求的绩点
						 */
						if (f1 > 0 && (double) i4 <= mainStu * param.getREWARD_RATE_IN_FIRST_REWARD()
								&& avgGrade > param.getREWARD_RATE_IN_FIRST_REWARD_IN_AVG_GRADE()) {
							sgqEntity.setReward(1);
							f1--;
							mainReward--;
						} else if (f2 > 0 && (double) i4 <= mainStu * param.getREWARD_RATE_IN_SECOND_REWARD()
								&& avgGrade > param.getREWARD_RATE_IN_SECOND_REWARD_IN_AVG_GRADE()) {
							sgqEntity.setReward(2);
							f2--;
							mainReward--;
						} else if (f3 > 0 && (double) i4 <= mainStu * param.getREWARD_RATE_IN_THIRD_REWARD()
								&& avgGrade > param.getREWARD_RATE_IN_THIRD_REWARD_IN_AVG_GRADE()) {
							sgqEntity.setReward(3);
							f3--;
							mainReward--;
						}
						if (mainReward <= 0) {
							canContinue = false;
						}

					}

				}
			}
			/**
			 * 如果奖学金的名额有剩余，则应写入记录
			 */
			rewardsNum = new HashMap<>();
			rewardsNum.put(REWARD_NAME[0], f1);
			rewardsNum.put(REWARD_NAME[1], f2);
			rewardsNum.put(REWARD_NAME[2], f3);
			rewardsNum.put(REWARD_NAME[REWARD_NAME.length - 1], mainReward);
		}
	}

	/**
	 * 保存贫困信息
	 * 
	 * @param list
	 */
	public void savePovertyMessage(List<PovertyMessage> list) {
		povertyMap = new HashMap<>();
		for (PovertyMessage msg : list) {
			povertyMap.put(msg.getStudentId(), msg.getLevel());
		}
	}

	public Integer getPovertyLevel(String id) {
		if (StringUtils.isEmpty(id)) {
			return null;
		} else {
			return povertyMap.get(id);
		}
	}

	public String getPovertyLevelString(String value, String id) {
		Integer povertyLevel = getPovertyLevel(id);
		if(povertyLevel==null){
			return "";
		}
		String[] split = value.split("@");
		return split[povertyLevel-1];
	}

	public String getAcademicYear() {
		return academicYear;
	}

	public void setAcademicYear(String academicYear) {
		this.academicYear = academicYear;
	}

	public Integer getItem() {
		return item;
	}

	public void setItem(Integer item) {
		this.item = item;
	}

	public Map<String, Integer> getSubjectCount() {
		return subjectCount;
	}

	public void setSubjectCount(Map<String, Integer> subjectCount) {
		this.subjectCount = subjectCount;
	}

	public List<String> getClas() {
		return clas;
	}

	public void setClas(List<String> clas) {
		this.clas = clas;
	}

	public Integer getMainCount() {
		return mainCount;
	}

	public void setMainCount(Integer mainCount) {
		this.mainCount = mainCount;
	}

	public Map<String, SGQEntity> getStuMessage() {
		return stuMessage;
	}

	public SGQMainMessageEntity(String academicYear, Integer item, Map<String, Integer> subjectCount,
			List<String> academy, List<String> clas, Integer mainCount, Map<String, SGQEntity> stuMessage) {
		super();
		this.academicYear = academicYear;
		this.item = item;
		this.subjectCount = subjectCount;
		this.clas = clas;
		this.mainCount = mainCount;
		this.stuMessage = stuMessage;
		this.academy = academy;
	}

	public Map<String, Double> getSubjectNum() {
		return subjectNum;
	}

	public void setSubjectNum(Map<String, Double> subjectNum) {
		this.subjectNum = subjectNum;
	}

	public ExcelStaticParam getParam() {
		return param;
	}

	public void setParam(ExcelStaticParam param) {
		this.param = param;
	}

	public Map<String, Integer> getRewardsNum() {
		return rewardsNum;
	}

	public void setRewardsNum(Map<String, Integer> rewardsNum) {
		this.rewardsNum = rewardsNum;
	}

	public String getFlag() {
		return flag;
	}

	public void setFlag(String flag) {
		this.flag = flag;
	}

	public Map<String, Boolean> getSubjectBool() {
		return subjectBool;
	}

	public void setSubjectBool(Map<String, Boolean> subjectBool) {
		this.subjectBool = subjectBool;
	}

	public List<String> getAcademy() {
		return academy;
	}

	public void setAcademy(List<String> academy) {
		this.academy = academy;
	}

	public boolean isNewTable() {
		return isNewTable;
	}

	public void setNewTable(boolean isNewTable) {
		this.isNewTable = isNewTable;
	}
}

class DoubleSort {
	/**
	 * 从大到小排序并获得排序后的排名映射 从1开始
	 * 
	 * @param courseGradeList
	 * @return
	 */
	public static Map<Double, Integer> getOrder(List<Double> courseGradeList) {
		Map<Double, Integer> map = new HashMap<>();
		/**
		 * 从大到小排序
		 */
		courseGradeList.sort(new Comparator<Double>() {
			@Override
			public int compare(Double o1, Double o2) {
				if (o1 == null || o2 == null) {
					return 1;
				}
				if (o1 > o2) {
					return -1;
				}
				if (o1 < o2) {
					return 1;
				}
				return 0;
			}
		});
		for (int i = 0; i < courseGradeList.size(); i++) {
			if (map.containsKey(courseGradeList.get(i))) {
				continue;
			}
			map.put(courseGradeList.get(i), i + 1);
		}
		return map;
	}

}
